/***************************************************************************
 *  JLayerME is a JAVA library that decodes/plays/converts MPEG 1/2 Layer 3.
 *  Project Homepage: http://www.javazoom.net/javalayer/javalayerme.html.
 *  Copyright (C) JavaZOOM 1999-2005.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *---------------------------------------------------------------------------
 *   19 Aug 2004 - Konstantin Belous 
 *   Added code for MPEG 2 support 
 *   (used the mpglib (http://ftp.tu-clausthal.de/pub/unix/audio/mpg123) as the source for changes).  
 *---------------------------------------------------------------------------
 *   12 Aug 2004 Konstantin Belous 
 *   Replaced the Arrays.fill() call in the stereo() method 
 *   with the fill in the loop with purposes of compatibility to Java 1.1. 
 *---------------------------------------------------------------------------
 */
package javazoom.jlme.decoder;


import java.util.Arrays;

final class LayerIIIDecoder {

    private final static int pretab[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0};

    private final static float two_to_negative_half_pow[] =
            {1.0000000000E+00f, 7.0710678119E-01f, 5.0000000000E-01f, 3.5355339059E-01f,
            2.5000000000E-01f, 1.7677669530E-01f, 1.2500000000E-01f, 8.8388347648E-02f,
            6.2500000000E-02f, 4.4194173824E-02f, 3.1250000000E-02f, 2.2097086912E-02f,
            1.5625000000E-02f, 1.1048543456E-02f, 7.8125000000E-03f, 5.5242717280E-03f,
            3.9062500000E-03f, 2.7621358640E-03f, 1.9531250000E-03f, 1.3810679320E-03f,
            9.7656250000E-04f, 6.9053396600E-04f, 4.8828125000E-04f, 3.4526698300E-04f,
            2.4414062500E-04f, 1.7263349150E-04f, 1.2207031250E-04f, 8.6316745750E-05f,
            6.1035156250E-05f, 4.3158372875E-05f, 3.0517578125E-05f, 2.1579186438E-05f,
            1.5258789062E-05f, 1.0789593219E-05f, 7.6293945312E-06f, 5.3947966094E-06f,
            3.8146972656E-06f, 2.6973983047E-06f, 1.9073486328E-06f, 1.3486991523E-06f,
            9.5367431641E-07f, 6.7434957617E-07f, 4.7683715820E-07f, 3.3717478809E-07f,
            2.3841857910E-07f, 1.6858739404E-07f, 1.1920928955E-07f, 8.4293697022E-08f,
            5.9604644775E-08f, 4.2146848511E-08f, 2.9802322388E-08f, 2.1073424255E-08f,
            1.4901161194E-08f, 1.0536712128E-08f, 7.4505805969E-09f, 5.2683560639E-09f,
            3.7252902985E-09f, 2.6341780319E-09f, 1.8626451492E-09f, 1.3170890160E-09f,
            9.3132257462E-10f, 6.5854450798E-10f, 4.6566128731E-10f, 3.2927225399E-10f
            };

    private final static float t_43[];

    static{
       t_43 = new float[8192];
       double d43 = (4.0 / 3.0);
       for (int i = 0; i < 8192; i++)
         t_43[i] = (float) Math.pow(i, d43);
    }

   private final static float TAN12[] =
            {
            0.0f, 0.26794919f, 0.57735027f, 1.0f,
            1.73205081f, 3.73205081f, 9.9999999e10f, -3.73205081f,
            -1.73205081f, -1.0f, -0.57735027f, -0.26794919f,
            0.0f, 0.26794919f, 0.57735027f, 1.0f
            };

    private final static float win[][] =
            {
            {-1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f,
            -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f,
            -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f,
            -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f,
            -4.0715656898E-01f, -3.6969460527E-01f, -3.3876269197E-01f, -3.1242222492E-01f,
            -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f,
            -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f,
            -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f,
            -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f},
            {-1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f,
            -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f,
            -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f,
            -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f,
            -4.0715656898E-01f, -3.6969460527E-01f, -3.3908542600E-01f, -3.1511810350E-01f,
            -2.9642226150E-01f, -2.8184548650E-01f, -5.4119610000E-01f, -2.6213228100E-01f,
            -2.5387916537E-01f, -2.3296291359E-01f, -1.9852728987E-01f, -1.5233534808E-01f,
            -9.6496400054E-02f, -3.3423828516E-02f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f},
            {-4.8300800645E-02f, -1.5715656932E-01f, -2.8325045177E-01f, -4.2953747763E-01f,
            -1.2071067795E+00f, -8.2426483178E-01f, -1.1451749106E+00f, -1.7695290101E+00f,
            -4.5470225061E+00f, -3.4890531002E+00f, -7.3296292804E-01f, -1.5076514758E-01f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f},
            {0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
            0.0000000000E+00f, 0.0000000000E+00f, -1.5076513660E-01f, -7.3296291107E-01f,
            -3.4890530566E+00f, -4.5470224727E+00f, -1.7695290031E+00f, -1.1451749092E+00f,
            -8.3137738100E-01f, -1.3065629650E+00f, -5.4142014250E-01f, -4.6528974900E-01f,
            -4.1066990750E-01f, -3.7004680800E-01f, -3.3876269197E-01f, -3.1242222492E-01f,
            -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f,
            -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f,
            -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f,
            -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f}
            };
    
    private static int reorder_table[][] = /* this array is a huge tax on the system */
            {
            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
            17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
            34, 27, 31, 35, 36, 42, 48, 37, 43, 49, 38, 44, 50, 39, 45, 51,
            40, 46, 52, 41, 47, 53, 54, 60, 66, 55, 61, 67, 56, 62, 68, 57,
            63, 69, 58, 64, 70, 59, 65, 71, 72, 80, 88, 73, 81, 89, 74, 82,
            90, 75, 83, 91, 76, 84, 92, 77, 85, 93, 78, 86, 94, 79, 87, 95,
            96, 106, 116, 97, 107, 117, 98, 108, 118, 99, 109, 119, 100, 110, 120, 101,
            111, 121, 102, 112, 122, 103, 113, 123, 104, 114, 124, 105, 115, 125, 126, 140,
            154, 127, 141, 155, 128, 142, 156, 129, 143, 157, 130, 144, 158, 131, 145, 159,
            132, 146, 160, 133, 147, 161, 134, 148, 162, 135, 149, 163, 136, 150, 164, 137,
            151, 165, 138, 152, 166, 139, 153, 167, 168, 186, 204, 169, 187, 205, 170, 188,
            206, 171, 189, 207, 172, 190, 208, 173, 191, 209, 174, 192, 210, 175, 193, 211,
            176, 194, 212, 177, 195, 213, 178, 196, 214, 179, 197, 215, 180, 198, 216, 181,
            199, 217, 182, 200, 218, 183, 201, 219, 184, 202, 220, 185, 203, 221, 222, 248,
            274, 223, 249, 275, 224, 250, 276, 225, 251, 277, 226, 252, 278, 227, 253, 279,
            228, 254, 280, 229, 255, 281, 230, 256, 282, 231, 257, 283, 232, 258, 284, 233,
            259, 285, 234, 260, 286, 235, 261, 287, 236, 262, 288, 237, 263, 289, 238, 264,
            290, 239, 265, 291, 240, 266, 292, 241, 267, 293, 242, 268, 294, 243, 269, 295,
            244, 270, 296, 245, 271, 297, 246, 272, 298, 247, 273, 299, 300, 332, 364, 301,
            333, 365, 302, 334, 366, 303, 335, 367, 304, 336, 368, 305, 337, 369, 306, 338,
            370, 307, 339, 371, 308, 340, 372, 309, 341, 373, 310, 342, 374, 311, 343, 375,
            312, 344, 376, 313, 345, 377, 314, 346, 378, 315, 347, 379, 316, 348, 380, 317,
            349, 381, 318, 350, 382, 319, 351, 383, 320, 352, 384, 321, 353, 385, 322, 354,
            386, 323, 355, 387, 324, 356, 388, 325, 357, 389, 326, 358, 390, 327, 359, 391,
            328, 360, 392, 329, 361, 393, 330, 362, 394, 331, 363, 395, 396, 438, 480, 397,
            439, 481, 398, 440, 482, 399, 441, 483, 400, 442, 484, 401, 443, 485, 402, 444,
            486, 403, 445, 487, 404, 446, 488, 405, 447, 489, 406, 448, 490, 407, 449, 491,
            408, 450, 492, 409, 451, 493, 410, 452, 494, 411, 453, 495, 412, 454, 496, 413,
            455, 497, 414, 456, 498, 415, 457, 499, 416, 458, 500, 417, 459, 501, 418, 460,
            502, 419, 461, 503, 420, 462, 504, 421, 463, 505, 422, 464, 506, 423, 465, 507,
            424, 466, 508, 425, 467, 509, 426, 468, 510, 427, 469, 511, 428, 470, 512, 429,
            471, 513, 430, 472, 514, 431, 473, 515, 432, 474, 516, 433, 475, 517, 434, 476,
            518, 435, 477, 519, 436, 478, 520, 437, 479, 521, 522, 540, 558, 523, 541, 559,
            524, 542, 560, 525, 543, 561, 526, 544, 562, 527, 545, 563, 528, 546, 564, 529,
            547, 565, 530, 548, 566, 531, 549, 567, 532, 550, 568, 533, 551, 569, 534, 552,
            570, 535, 553, 571, 536, 554, 572, 537, 555, 573, 538, 556, 574, 539, 557, 575},
            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
            17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
            34, 27, 31, 35, 36, 42, 48, 37, 43, 49, 38, 44, 50, 39, 45, 51,
            40, 46, 52, 41, 47, 53, 54, 62, 70, 55, 63, 71, 56, 64, 72, 57,
            65, 73, 58, 66, 74, 59, 67, 75, 60, 68, 76, 61, 69, 77, 78, 88,
            98, 79, 89, 99, 80, 90, 100, 81, 91, 101, 82, 92, 102, 83, 93, 103,
            84, 94, 104, 85, 95, 105, 86, 96, 106, 87, 97, 107, 108, 120, 132, 109,
            121, 133, 110, 122, 134, 111, 123, 135, 112, 124, 136, 113, 125, 137, 114, 126,
            138, 115, 127, 139, 116, 128, 140, 117, 129, 141, 118, 130, 142, 119, 131, 143,
            144, 158, 172, 145, 159, 173, 146, 160, 174, 147, 161, 175, 148, 162, 176, 149,
            163, 177, 150, 164, 178, 151, 165, 179, 152, 166, 180, 153, 167, 181, 154, 168,
            182, 155, 169, 183, 156, 170, 184, 157, 171, 185, 186, 204, 222, 187, 205, 223,
            188, 206, 224, 189, 207, 225, 190, 208, 226, 191, 209, 227, 192, 210, 228, 193,
            211, 229, 194, 212, 230, 195, 213, 231, 196, 214, 232, 197, 215, 233, 198, 216,
            234, 199, 217, 235, 200, 218, 236, 201, 219, 237, 202, 220, 238, 203, 221, 239,
            240, 264, 288, 241, 265, 289, 242, 266, 290, 243, 267, 291, 244, 268, 292, 245,
            269, 293, 246, 270, 294, 247, 271, 295, 248, 272, 296, 249, 273, 297, 250, 274,
            298, 251, 275, 299, 252, 276, 300, 253, 277, 301, 254, 278, 302, 255, 279, 303,
            256, 280, 304, 257, 281, 305, 258, 282, 306, 259, 283, 307, 260, 284, 308, 261,
            285, 309, 262, 286, 310, 263, 287, 311, 312, 344, 376, 313, 345, 377, 314, 346,
            378, 315, 347, 379, 316, 348, 380, 317, 349, 381, 318, 350, 382, 319, 351, 383,
            320, 352, 384, 321, 353, 385, 322, 354, 386, 323, 355, 387, 324, 356, 388, 325,
            357, 389, 326, 358, 390, 327, 359, 391, 328, 360, 392, 329, 361, 393, 330, 362,
            394, 331, 363, 395, 332, 364, 396, 333, 365, 397, 334, 366, 398, 335, 367, 399,
            336, 368, 400, 337, 369, 401, 338, 370, 402, 339, 371, 403, 340, 372, 404, 341,
            373, 405, 342, 374, 406, 343, 375, 407, 408, 452, 496, 409, 453, 497, 410, 454,
            498, 411, 455, 499, 412, 456, 500, 413, 457, 501, 414, 458, 502, 415, 459, 503,
            416, 460, 504, 417, 461, 505, 418, 462, 506, 419, 463, 507, 420, 464, 508, 421,
            465, 509, 422, 466, 510, 423, 467, 511, 424, 468, 512, 425, 469, 513, 426, 470,
            514, 427, 471, 515, 428, 472, 516, 429, 473, 517, 430, 474, 518, 431, 475, 519,
            432, 476, 520, 433, 477, 521, 434, 478, 522, 435, 479, 523, 436, 480, 524, 437,
            481, 525, 438, 482, 526, 439, 483, 527, 440, 484, 528, 441, 485, 529, 442, 486,
            530, 443, 487, 531, 444, 488, 532, 445, 489, 533, 446, 490, 534, 447, 491, 535,
            448, 492, 536, 449, 493, 537, 450, 494, 538, 451, 495, 539, 540, 552, 564, 541,
            553, 565, 542, 554, 566, 543, 555, 567, 544, 556, 568, 545, 557, 569, 546, 558,
            570, 547, 559, 571, 548, 560, 572, 549, 561, 573, 550, 562, 574, 551, 563, 575},
            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
            17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
            34, 27, 31, 35, 36, 42, 48, 37, 43, 49, 38, 44, 50, 39, 45, 51,
            40, 46, 52, 41, 47, 53, 54, 62, 70, 55, 63, 71, 56, 64, 72, 57,
            65, 73, 58, 66, 74, 59, 67, 75, 60, 68, 76, 61, 69, 77, 78, 88,
            98, 79, 89, 99, 80, 90, 100, 81, 91, 101, 82, 92, 102, 83, 93, 103,
            84, 94, 104, 85, 95, 105, 86, 96, 106, 87, 97, 107, 108, 120, 132, 109,
            121, 133, 110, 122, 134, 111, 123, 135, 112, 124, 136, 113, 125, 137, 114, 126,
            138, 115, 127, 139, 116, 128, 140, 117, 129, 141, 118, 130, 142, 119, 131, 143,
            144, 158, 172, 145, 159, 173, 146, 160, 174, 147, 161, 175, 148, 162, 176, 149,
            163, 177, 150, 164, 178, 151, 165, 179, 152, 166, 180, 153, 167, 181, 154, 168,
            182, 155, 169, 183, 156, 170, 184, 157, 171, 185, 186, 204, 222, 187, 205, 223,
            188, 206, 224, 189, 207, 225, 190, 208, 226, 191, 209, 227, 192, 210, 228, 193,
            211, 229, 194, 212, 230, 195, 213, 231, 196, 214, 232, 197, 215, 233, 198, 216,
            234, 199, 217, 235, 200, 218, 236, 201, 219, 237, 202, 220, 238, 203, 221, 239,
            240, 264, 288, 241, 265, 289, 242, 266, 290, 243, 267, 291, 244, 268, 292, 245,
            269, 293, 246, 270, 294, 247, 271, 295, 248, 272, 296, 249, 273, 297, 250, 274,
            298, 251, 275, 299, 252, 276, 300, 253, 277, 301, 254, 278, 302, 255, 279, 303,
            256, 280, 304, 257, 281, 305, 258, 282, 306, 259, 283, 307, 260, 284, 308, 261,
            285, 309, 262, 286, 310, 263, 287, 311, 312, 342, 372, 313, 343, 373, 314, 344,
            374, 315, 345, 375, 316, 346, 376, 317, 347, 377, 318, 348, 378, 319, 349, 379,
            320, 350, 380, 321, 351, 381, 322, 352, 382, 323, 353, 383, 324, 354, 384, 325,
            355, 385, 326, 356, 386, 327, 357, 387, 328, 358, 388, 329, 359, 389, 330, 360,
            390, 331, 361, 391, 332, 362, 392, 333, 363, 393, 334, 364, 394, 335, 365, 395,
            336, 366, 396, 337, 367, 397, 338, 368, 398, 339, 369, 399, 340, 370, 400, 341,
            371, 401, 402, 442, 482, 403, 443, 483, 404, 444, 484, 405, 445, 485, 406, 446,
            486, 407, 447, 487, 408, 448, 488, 409, 449, 489, 410, 450, 490, 411, 451, 491,
            412, 452, 492, 413, 453, 493, 414, 454, 494, 415, 455, 495, 416, 456, 496, 417,
            457, 497, 418, 458, 498, 419, 459, 499, 420, 460, 500, 421, 461, 501, 422, 462,
            502, 423, 463, 503, 424, 464, 504, 425, 465, 505, 426, 466, 506, 427, 467, 507,
            428, 468, 508, 429, 469, 509, 430, 470, 510, 431, 471, 511, 432, 472, 512, 433,
            473, 513, 434, 474, 514, 435, 475, 515, 436, 476, 516, 437, 477, 517, 438, 478,
            518, 439, 479, 519, 440, 480, 520, 441, 481, 521, 522, 540, 558, 523, 541, 559,
            524, 542, 560, 525, 543, 561, 526, 544, 562, 527, 545, 563, 528, 546, 564, 529,
            547, 565, 530, 548, 566, 531, 549, 567, 532, 550, 568, 533, 551, 569, 534, 552,
            570, 535, 553, 571, 536, 554, 572, 537, 555, 573, 538, 556, 574, 539, 557, 575},
            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
            17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
            34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47,
            48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52, 58, 64, 53,
            59, 65, 66, 74, 82, 67, 75, 83, 68, 76, 84, 69, 77, 85, 70, 78,
            86, 71, 79, 87, 72, 80, 88, 73, 81, 89, 90, 100, 110, 91, 101, 111,
            92, 102, 112, 93, 103, 113, 94, 104, 114, 95, 105, 115, 96, 106, 116, 97,
            107, 117, 98, 108, 118, 99, 109, 119, 120, 132, 144, 121, 133, 145, 122, 134,
            146, 123, 135, 147, 124, 136, 148, 125, 137, 149, 126, 138, 150, 127, 139, 151,
            128, 140, 152, 129, 141, 153, 130, 142, 154, 131, 143, 155, 156, 170, 184, 157,
            171, 185, 158, 172, 186, 159, 173, 187, 160, 174, 188, 161, 175, 189, 162, 176,
            190, 163, 177, 191, 164, 178, 192, 165, 179, 193, 166, 180, 194, 167, 181, 195,
            168, 182, 196, 169, 183, 197, 198, 216, 234, 199, 217, 235, 200, 218, 236, 201,
            219, 237, 202, 220, 238, 203, 221, 239, 204, 222, 240, 205, 223, 241, 206, 224,
            242, 207, 225, 243, 208, 226, 244, 209, 227, 245, 210, 228, 246, 211, 229, 247,
            212, 230, 248, 213, 231, 249, 214, 232, 250, 215, 233, 251, 252, 274, 296, 253,
            275, 297, 254, 276, 298, 255, 277, 299, 256, 278, 300, 257, 279, 301, 258, 280,
            302, 259, 281, 303, 260, 282, 304, 261, 283, 305, 262, 284, 306, 263, 285, 307,
            264, 286, 308, 265, 287, 309, 266, 288, 310, 267, 289, 311, 268, 290, 312, 269,
            291, 313, 270, 292, 314, 271, 293, 315, 272, 294, 316, 273, 295, 317, 318, 348,
            378, 319, 349, 379, 320, 350, 380, 321, 351, 381, 322, 352, 382, 323, 353, 383,
            324, 354, 384, 325, 355, 385, 326, 356, 386, 327, 357, 387, 328, 358, 388, 329,
            359, 389, 330, 360, 390, 331, 361, 391, 332, 362, 392, 333, 363, 393, 334, 364,
            394, 335, 365, 395, 336, 366, 396, 337, 367, 397, 338, 368, 398, 339, 369, 399,
            340, 370, 400, 341, 371, 401, 342, 372, 402, 343, 373, 403, 344, 374, 404, 345,
            375, 405, 346, 376, 406, 347, 377, 407, 408, 464, 520, 409, 465, 521, 410, 466,
            522, 411, 467, 523, 412, 468, 524, 413, 469, 525, 414, 470, 526, 415, 471, 527,
            416, 472, 528, 417, 473, 529, 418, 474, 530, 419, 475, 531, 420, 476, 532, 421,
            477, 533, 422, 478, 534, 423, 479, 535, 424, 480, 536, 425, 481, 537, 426, 482,
            538, 427, 483, 539, 428, 484, 540, 429, 485, 541, 430, 486, 542, 431, 487, 543,
            432, 488, 544, 433, 489, 545, 434, 490, 546, 435, 491, 547, 436, 492, 548, 437,
            493, 549, 438, 494, 550, 439, 495, 551, 440, 496, 552, 441, 497, 553, 442, 498,
            554, 443, 499, 555, 444, 500, 556, 445, 501, 557, 446, 502, 558, 447, 503, 559,
            448, 504, 560, 449, 505, 561, 450, 506, 562, 451, 507, 563, 452, 508, 564, 453,
            509, 565, 454, 510, 566, 455, 511, 567, 456, 512, 568, 457, 513, 569, 458, 514,
            570, 459, 515, 571, 460, 516, 572, 461, 517, 573, 462, 518, 574, 463, 519, 575},
            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
            17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
            34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47,
            48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52, 58, 64, 53,
            59, 65, 66, 72, 78, 67, 73, 79, 68, 74, 80, 69, 75, 81, 70, 76,
            82, 71, 77, 83, 84, 94, 104, 85, 95, 105, 86, 96, 106, 87, 97, 107,
            88, 98, 108, 89, 99, 109, 90, 100, 110, 91, 101, 111, 92, 102, 112, 93,
            103, 113, 114, 126, 138, 115, 127, 139, 116, 128, 140, 117, 129, 141, 118, 130,
            142, 119, 131, 143, 120, 132, 144, 121, 133, 145, 122, 134, 146, 123, 135, 147,
            124, 136, 148, 125, 137, 149, 150, 164, 178, 151, 165, 179, 152, 166, 180, 153,
            167, 181, 154, 168, 182, 155, 169, 183, 156, 170, 184, 157, 171, 185, 158, 172,
            186, 159, 173, 187, 160, 174, 188, 161, 175, 189, 162, 176, 190, 163, 177, 191,
            192, 208, 224, 193, 209, 225, 194, 210, 226, 195, 211, 227, 196, 212, 228, 197,
            213, 229, 198, 214, 230, 199, 215, 231, 200, 216, 232, 201, 217, 233, 202, 218,
            234, 203, 219, 235, 204, 220, 236, 205, 221, 237, 206, 222, 238, 207, 223, 239,
            240, 260, 280, 241, 261, 281, 242, 262, 282, 243, 263, 283, 244, 264, 284, 245,
            265, 285, 246, 266, 286, 247, 267, 287, 248, 268, 288, 249, 269, 289, 250, 270,
            290, 251, 271, 291, 252, 272, 292, 253, 273, 293, 254, 274, 294, 255, 275, 295,
            256, 276, 296, 257, 277, 297, 258, 278, 298, 259, 279, 299, 300, 326, 352, 301,
            327, 353, 302, 328, 354, 303, 329, 355, 304, 330, 356, 305, 331, 357, 306, 332,
            358, 307, 333, 359, 308, 334, 360, 309, 335, 361, 310, 336, 362, 311, 337, 363,
            312, 338, 364, 313, 339, 365, 314, 340, 366, 315, 341, 367, 316, 342, 368, 317,
            343, 369, 318, 344, 370, 319, 345, 371, 320, 346, 372, 321, 347, 373, 322, 348,
            374, 323, 349, 375, 324, 350, 376, 325, 351, 377, 378, 444, 510, 379, 445, 511,
            380, 446, 512, 381, 447, 513, 382, 448, 514, 383, 449, 515, 384, 450, 516, 385,
            451, 517, 386, 452, 518, 387, 453, 519, 388, 454, 520, 389, 455, 521, 390, 456,
            522, 391, 457, 523, 392, 458, 524, 393, 459, 525, 394, 460, 526, 395, 461, 527,
            396, 462, 528, 397, 463, 529, 398, 464, 530, 399, 465, 531, 400, 466, 532, 401,
            467, 533, 402, 468, 534, 403, 469, 535, 404, 470, 536, 405, 471, 537, 406, 472,
            538, 407, 473, 539, 408, 474, 540, 409, 475, 541, 410, 476, 542, 411, 477, 543,
            412, 478, 544, 413, 479, 545, 414, 480, 546, 415, 481, 547, 416, 482, 548, 417,
            483, 549, 418, 484, 550, 419, 485, 551, 420, 486, 552, 421, 487, 553, 422, 488,
            554, 423, 489, 555, 424, 490, 556, 425, 491, 557, 426, 492, 558, 427, 493, 559,
            428, 494, 560, 429, 495, 561, 430, 496, 562, 431, 497, 563, 432, 498, 564, 433,
            499, 565, 434, 500, 566, 435, 501, 567, 436, 502, 568, 437, 503, 569, 438, 504,
            570, 439, 505, 571, 440, 506, 572, 441, 507, 573, 442, 508, 574, 443, 509, 575},
            {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
            17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
            34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47,
            48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52, 58, 64, 53,
            59, 65, 66, 74, 82, 67, 75, 83, 68, 76, 84, 69, 77, 85, 70, 78,
            86, 71, 79, 87, 72, 80, 88, 73, 81, 89, 90, 102, 114, 91, 103, 115,
            92, 104, 116, 93, 105, 117, 94, 106, 118, 95, 107, 119, 96, 108, 120, 97,
            109, 121, 98, 110, 122, 99, 111, 123, 100, 112, 124, 101, 113, 125, 126, 142,
            158, 127, 143, 159, 128, 144, 160, 129, 145, 161, 130, 146, 162, 131, 147, 163,
            132, 148, 164, 133, 149, 165, 134, 150, 166, 135, 151, 167, 136, 152, 168, 137,
            153, 169, 138, 154, 170, 139, 155, 171, 140, 156, 172, 141, 157, 173, 174, 194,
            214, 175, 195, 215, 176, 196, 216, 177, 197, 217, 178, 198, 218, 179, 199, 219,
            180, 200, 220, 181, 201, 221, 182, 202, 222, 183, 203, 223, 184, 204, 224, 185,
            205, 225, 186, 206, 226, 187, 207, 227, 188, 208, 228, 189, 209, 229, 190, 210,
            230, 191, 211, 231, 192, 212, 232, 193, 213, 233, 234, 260, 286, 235, 261, 287,
            236, 262, 288, 237, 263, 289, 238, 264, 290, 239, 265, 291, 240, 266, 292, 241,
            267, 293, 242, 268, 294, 243, 269, 295, 244, 270, 296, 245, 271, 297, 246, 272,
            298, 247, 273, 299, 248, 274, 300, 249, 275, 301, 250, 276, 302, 251, 277, 303,
            252, 278, 304, 253, 279, 305, 254, 280, 306, 255, 281, 307, 256, 282, 308, 257,
            283, 309, 258, 284, 310, 259, 285, 311, 312, 346, 380, 313, 347, 381, 314, 348,
            382, 315, 349, 383, 316, 350, 384, 317, 351, 385, 318, 352, 386, 319, 353, 387,
            320, 354, 388, 321, 355, 389, 322, 356, 390, 323, 357, 391, 324, 358, 392, 325,
            359, 393, 326, 360, 394, 327, 361, 395, 328, 362, 396, 329, 363, 397, 330, 364,
            398, 331, 365, 399, 332, 366, 400, 333, 367, 401, 334, 368, 402, 335, 369, 403,
            336, 370, 404, 337, 371, 405, 338, 372, 406, 339, 373, 407, 340, 374, 408, 341,
            375, 409, 342, 376, 410, 343, 377, 411, 344, 378, 412, 345, 379, 413, 414, 456,
            498, 415, 457, 499, 416, 458, 500, 417, 459, 501, 418, 460, 502, 419, 461, 503,
            420, 462, 504, 421, 463, 505, 422, 464, 506, 423, 465, 507, 424, 466, 508, 425,
            467, 509, 426, 468, 510, 427, 469, 511, 428, 470, 512, 429, 471, 513, 430, 472,
            514, 431, 473, 515, 432, 474, 516, 433, 475, 517, 434, 476, 518, 435, 477, 519,
            436, 478, 520, 437, 479, 521, 438, 480, 522, 439, 481, 523, 440, 482, 524, 441,
            483, 525, 442, 484, 526, 443, 485, 527, 444, 486, 528, 445, 487, 529, 446, 488,
            530, 447, 489, 531, 448, 490, 532, 449, 491, 533, 450, 492, 534, 451, 493, 535,
            452, 494, 536, 453, 495, 537, 454, 496, 538, 455, 497, 539, 540, 552, 564, 541,
            553, 565, 542, 554, 566, 543, 555, 567, 544, 556, 568, 545, 557, 569, 546, 558,
            570, 547, 559, 571, 548, 560, 572, 549, 561, 573, 550, 562, 574, 551, 563, 575}
            };

    private final static int SSLIMIT = 18;
    private final static int SBLIMIT = 32;

    final static int slen0[] ={0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4};
    final static int slen1[] ={0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3};

    private final HuffmanTables.Huffman huff = new HuffmanTables.Huffman();

    private final int[] is_pos = new int[576];
    private final float[] is_ratio = new float[576];

    private final float[] tsOutCopy = new float[18];
    private final float[] rawout = new float[36];
    private final int[] is_1d = new int[SBLIMIT * SSLIMIT + 4];
    private final float[][][] ro = new float[2][SBLIMIT][SSLIMIT];
    private final float[][][] lr = new float[2][SBLIMIT][SSLIMIT];
    private final float[] out_1d = new float[SBLIMIT * SSLIMIT];
    private final float[][] prevblck = new float[2][SBLIMIT * SSLIMIT];
    private final float[][] k = new float[2][SBLIMIT * SSLIMIT];
    private int nonzero0, nonzero1;
    private BitStream stream;
    private Header header;
    private SynthesisFilter filter1, filter2;
    private SampleBuffer buffer;
    private int which_channels;
    public BitReserve br;
    private SideInfo si;

    public int[] scalefac0L= new int[23];
    public int[][] scalefac0S= new int[3][13];
    public int[] scalefac1L= new int[23];
    public int[][] scalefac1S= new int[3][13];

    private int max_gr;
    private int frame_start;
    private int part2_start;
    private int channels;
    private int first_channel;
    private int last_channel;
    private int sfreq;

    private final float[] samples1 = new float[32];
    private final float[] samples2 = new float[32];

    private int[] sfBandIndexL;
    private int[] sfBandIndexS;
    private HuffmanTables h;
    private HuffmanTables hDecoder;


    public LayerIIIDecoder(BitReserve br, BitStream stream0, Header header0, SynthesisFilter filtera, SynthesisFilter filterb, SampleBuffer buffer0, int which_ch0) {
        stream = stream0;
        header = header0;
        filter1 = filtera;
        filter2 = filterb;
        buffer = buffer0;
        which_channels = which_ch0;
        frame_start = 0;
        channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2;
        max_gr = (header.version() == Header.MPEG1) ? 2 : 1;
        sfreq = header.sample_frequency() + ((header.version() == Header.MPEG1) ? 3 : 0);
        switch(sfreq){
          case 0:
            sfBandIndexL = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576};
            sfBandIndexS = new int[]{0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192};
          break;
          case 1:
            sfBandIndexL = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 330, 394, 464, 540, 576};
            sfBandIndexS = new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192};
          break;
          case 2:
            sfBandIndexL = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576};
            sfBandIndexS = new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192};
          break;
          case 3:
            sfBandIndexL = new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576};
            sfBandIndexS = new int[]{0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192};
          break;
          case 4:
            sfBandIndexL = new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576};
            sfBandIndexS = new int[]{0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192};
          break;
          case 5:
            sfBandIndexL = new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576};
            sfBandIndexS = new int[]{0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192};
          break;
        }

        if (channels == 2) {
            switch (which_channels) {
                case OutputChannels.LEFT_CHANNEL:
                case OutputChannels.DOWNMIX_CHANNELS:
                    first_channel = last_channel = 0;
                    break;
                case OutputChannels.RIGHT_CHANNEL:
                    first_channel = last_channel = 1;
                    break;
                case OutputChannels.BOTH_CHANNELS:
                default:
                    first_channel = 0;
                    last_channel = 1;
                    break;
            }
        }
        else {
            first_channel = last_channel = 0;
        }
        for (int ch = 0; ch < 2; ch++) {
            for (int j = 0; j < 576; j++) {
                prevblck[ch][j] = 0.0f;
            }
        }
        nonzero0 = nonzero1 = 576;
        this.br = br;
        si = new SideInfo();
        h = new HuffmanTables();
        hDecoder = new HuffmanTables();
    }

    public final void decodeFrame() {
        int nSlots = header.slots();
        get_side_info();

        for (int i = 0; i < nSlots; i++) {
            br.hputbuf(stream.readbits(8));
        }
        int main_data_end = br.totbit >>> 3;
        int flush_main = (br.totbit & 7);
        if (flush_main != 0) {
            br.hgetbits(8 - flush_main);
            main_data_end++;
        }

        // E.B Fix.
        int bytes_to_discard = frame_start - main_data_end - si.main_data_begin;
        frame_start += nSlots;
        if(bytes_to_discard < 0)
          return;


        /*int bytes_to_discard = frame_start - main_data_end - si.main_data_begin;
        if(bytes_to_discard < 0)
          return;

        frame_start += nSlots;*/
        // End of E.B Fix.
        
        if (main_data_end > 4096) {
            frame_start -= 4096;
            br.rewindNbytes(4096);
        }

        while(bytes_to_discard-->0)
          br.hgetbits(8);

        for (int gr = 0; gr < max_gr; gr++) {
            for (int ch = 0; ch < channels; ch++) {
                part2_start = br.totbit;
				if(header.version() == Header.MPEG1) {
					get_scale_factors_1(ch, gr);
				} else {
					get_scale_factors_2(ch, gr);
				}
                huffman_decode(ch, gr);
                dequantize_sample(ro[ch], ch, gr);
            }

            stereo(gr);

            for (int ch = first_channel; ch <= last_channel; ch++) {
                reorder(lr[ch], ch, gr);
                antialias(ch, gr);
                hybrid(ch, gr);

                for(int sb18 = 18; sb18 < 576; sb18 += 36){
                  for(int ss=1; ss < SSLIMIT; ss += 2){
                    out_1d[sb18 + ss] *= -1;
                  }
                }

                if ((ch == 0) || (which_channels == OutputChannels.RIGHT_CHANNEL)) {
                    for(int ss=0; ss < SSLIMIT; ss++){
                      for(int sb18 = 0, sb = 0; sb18 < 576; sb18 += 18){
                        samples1[sb++] = out_1d[sb18 + ss];
                      }
                      filter1.calculateSamples(samples1, buffer);
                    }
                }
                else {
                    for(int ss=0; ss < SSLIMIT; ss++){
                      for(int sb18 = 0, sb = 0; sb18 < 576; sb18 += 18){
                        samples2[sb++] = out_1d[sb18 + ss];
                      }
                      filter2.calculateSamples(samples2, buffer);
                    }

                }
            }
        }
    }

  public void invMDCT(final float[] in, final float[] out, final int block_type) {
    if (block_type == 2) {
      for(int i=0; i<36; i++)
        out[i] = 0;

      int six_i = 0;
      for (int i = 0; i < 3; i++) {
        // 12 point IMDCT
        // Begin 12 point IDCT
        // Input aliasing for 12 pt IDCT
        int curr0 = 15+i;
        int curr1 = 12+i;
        int curr2 = 9+i;
        int curr3 = 6+i;
        int curr4 = 3+i;
        in[curr0] += in[curr1]; in[curr1] += in[curr2]; in[curr2] += in[curr3];
        in[curr3] += in[curr4]; in[curr4] += in[i];
        // Input aliasing on odd indices (for 6 point IDCT)
        in[curr0] += in[curr2]; in[curr2] += in[curr4];
        // 3 point IDCT on even indices
        float pp2 = in[curr1] * 0.500000000f;
        float pp1 = in[curr3] * 0.866025403f;
        float sum = in[i] + pp2;
        float tmpf_1 = in[i] - in[curr1];
        float tmpf_0 = sum + pp1;
        float tmpf_2 = sum - pp1;
        // End 3 point IDCT on even indices
        // 3 point IDCT on odd indices (for 6 point IDCT)
        pp2 = in[curr0] * 0.500000000f;
        pp1 = in[curr2] * 0.866025403f;
        sum = in[curr4] + pp2;
        float tmpf_4 = in[curr4] - in[curr0];
        float tmpf_5 = sum + pp1;
        float tmpf_3 = sum - pp1;
        // End 3 point IDCT on odd indices
        // Twiddle factors on odd indices (for 6 point IDCT)
        tmpf_3 *= 1.931851653f;
        tmpf_4 *= 0.707106781f;
        tmpf_5 *= 0.517638090f;
        // Output butterflies on 2 3 point IDCT's (for 6 point IDCT)
        float save = tmpf_0;
        tmpf_0 += tmpf_5;
        tmpf_5 = save - tmpf_5;
        save = tmpf_1;
        tmpf_1 += tmpf_4;
        tmpf_4 = save - tmpf_4;
        save = tmpf_2;
        tmpf_2 += tmpf_3;
        tmpf_3 = save - tmpf_3;
        // End 6 point IDCT
        // Twiddle factors on indices (for 12 point IDCT)
        tmpf_0 *= 0.504314480f;
        tmpf_1 *= 0.541196100f;
        tmpf_2 *= 0.630236207f;
        tmpf_3 *= 0.821339815f;
        tmpf_4 *= 1.306562965f;
        tmpf_5 *= 3.830648788f;
        // End 12 point IDCT
        // Shift to 12 point modified IDCT, multiply by window type 2
        float tmpf_8 = -tmpf_0 * 0.793353340f;
        float tmpf_9 = -tmpf_0 * 0.608761429f;
        float tmpf_7 = -tmpf_1 * 0.923879532f;
        float tmpf_10 = -tmpf_1 * 0.382683432f;
        float tmpf_6 = -tmpf_2 * 0.991444861f;
        float tmpf_11 = -tmpf_2 * 0.130526192f;
        tmpf_0 = tmpf_3;
        tmpf_1 = tmpf_4 * 0.382683432f;
        tmpf_2 = tmpf_5 * 0.608761429f;
        tmpf_3 = -tmpf_5 * 0.793353340f;
        tmpf_4 = -tmpf_4 * 0.923879532f;
        tmpf_5 = -tmpf_0 * 0.991444861f;
        tmpf_0 *= 0.130526192f;
        out[six_i + 6] += tmpf_0;
        out[six_i + 7] += tmpf_1;
        out[six_i + 8] += tmpf_2;
        out[six_i + 9] += tmpf_3;
        out[six_i + 10] += tmpf_4;
        out[six_i + 11] += tmpf_5;
        out[six_i + 12] += tmpf_6;
        out[six_i + 13] += tmpf_7;
        out[six_i + 14] += tmpf_8;
        out[six_i + 15] += tmpf_9;
        out[six_i + 16] += tmpf_10;
        out[six_i + 17] += tmpf_11;
        six_i += 6;
      }
    }
    else {
      // 36 point IDCT
      // input aliasing for 36 point IDCT
      in[17] += in[16]; in[16] += in[15]; in[15] += in[14]; in[14] += in[13];
      in[13] += in[12]; in[12] += in[11]; in[11] += in[10]; in[10] += in[9];
      in[9] += in[8]; in[8] += in[7]; in[7] += in[6]; in[6] += in[5];
      in[5] += in[4]; in[4] += in[3]; in[3] += in[2]; in[2] += in[1];
      in[1] += in[0];
      // 18 point IDCT for odd indices
      // input aliasing for 18 point IDCT
      in[17] += in[15]; in[15] += in[13]; in[13] += in[11]; in[11] += in[9];
      in[9] += in[7]; in[7] += in[5]; in[5] += in[3]; in[3] += in[1];

      // Fast 9 Point Inverse Discrete Cosine Transform
      //
      // By  Francois-Raymond Boyer
      //         mailto:boyerf@iro.umontreal.ca
      //         http://www.iro.umontreal.ca/~boyerf
      //
      // The code has been optimized for Intel processors
      //  (takes a lot of time to convert float to and from iternal FPU representation)
      //
      // It is a simple "factorization" of the IDCT matrix.
      // 9 point IDCT on even indices
      // 5 points on odd indices (not realy an IDCT)
      float i00 = in[0] + in[0];
      float iip12 = i00 + in[12];
      float tmp0 = iip12 + in[4] * 1.8793852415718f + in[8] * 1.532088886238f + in[16] * 0.34729635533386f;
      float tmp1 = i00 + in[4] - in[8] - in[12] - in[12] - in[16];
      float tmp2 = iip12 - in[4] * 0.34729635533386f - in[8] * 1.8793852415718f + in[16] * 1.532088886238f;
      float tmp3 = iip12 - in[4] * 1.532088886238f + in[8] * 0.34729635533386f - in[16] * 1.8793852415718f;
      float tmp4 = in[0] - in[4] + in[8] - in[12] + in[16];
      // 4 points on even indices
      float i66_ = in[6] * 1.732050808f; // Sqrt[3]
      float tmp0_ = in[2] * 1.9696155060244f + i66_ + in[10] * 1.2855752193731f + in[14] * 0.68404028665134f;
      float tmp1_ = (in[2] - in[10] - in[14]) * 1.732050808f;
      float tmp2_ = in[2] * 1.2855752193731f - i66_ - in[10] * 0.68404028665134f + in[14] * 1.9696155060244f;
      float tmp3_ = in[2] * 0.68404028665134f - i66_ + in[10] * 1.9696155060244f - in[14] * 1.2855752193731f;
      // 9 point IDCT on odd indices
      // 5 points on odd indices (not realy an IDCT)
      float i0 = in[1] + in[1];
      float i0p12 = i0 + in[13];
      float tmp0o = i0p12 + in[5] * 1.8793852415718f + in[9] * 1.532088886238f + in[17] * 0.34729635533386f;
      float tmp1o = i0 + in[5] - in[9] - in[13] - in[13] - in[17];
      float tmp2o = i0p12 - in[5] * 0.34729635533386f - in[9] * 1.8793852415718f + in[17] * 1.532088886238f;
      float tmp3o = i0p12 - in[5] * 1.532088886238f + in[9] * 0.34729635533386f - in[17] * 1.8793852415718f;
      float tmp4o = (in[1] - in[5] + in[9] - in[13] + in[17]) * 0.707106781f; // Twiddled
      // 4 points on even indices
      float i6_ = in[7] * 1.732050808f; // Sqrt[3]
      float tmp0_o = in[3] * 1.9696155060244f + i6_ + in[11] * 1.2855752193731f + in[15] * 0.68404028665134f;
      float tmp1_o = (in[3] - in[11] - in[15]) * 1.732050808f;
      float tmp2_o = in[3] * 1.2855752193731f - i6_ - in[11] * 0.68404028665134f + in[15] * 1.9696155060244f;
      float tmp3_o = in[3] * 0.68404028665134f - i6_ + in[11] * 1.9696155060244f - in[15] * 1.2855752193731f;
      // Twiddle factors on odd indices
      // and
      // Butterflies on 9 point IDCT's
      // and
      // twiddle factors for 36 point IDCT
      float e = tmp0 + tmp0_; float o = (tmp0o + tmp0_o) * 0.501909918f; float tmpf_0 = e + o; float tmpf_17 = e - o; e = tmp1 + tmp1_;
      o = (tmp1o + tmp1_o) * 0.517638090f; float tmpf_1 = e + o; float tmpf_16 = e - o;e = tmp2 + tmp2_; o = (tmp2o + tmp2_o) * 0.551688959f;
      float tmpf_2 = e + o; float tmpf_15 = e - o; e = tmp3 + tmp3_; o = (tmp3o + tmp3_o) * 0.610387294f; float tmpf_3 = e + o; float tmpf_14 = e - o;
      float tmpf_4 = tmp4 + tmp4o; float tmpf_13 = tmp4 - tmp4o; e = tmp3 - tmp3_; o = (tmp3o - tmp3_o) * 0.871723397f;
      float tmpf_5 = e + o; float tmpf_12 = e - o; e = tmp2 - tmp2_; o = (tmp2o - tmp2_o) * 1.183100792f; float tmpf_6 = e + o;
      float tmpf_11 = e - o; e = tmp1 - tmp1_; o = (tmp1o - tmp1_o) * 1.931851653f; float tmpf_7 = e + o; float tmpf_10 = e - o;
      e = tmp0 - tmp0_; o = (tmp0o - tmp0_o) * 5.736856623f; float tmpf_8 = e + o; float tmpf_9 = e - o;
      // end 36 point IDCT
      // shift to modified IDCT
      float[] win_bt = win[block_type];
      out[0] = -tmpf_9 * win_bt[0];
      out[1] = -tmpf_10 * win_bt[1];
      out[2] = -tmpf_11 * win_bt[2];
      out[3] = -tmpf_12 * win_bt[3];
      out[4] = -tmpf_13 * win_bt[4];
      out[5] = -tmpf_14 * win_bt[5];
      out[6] = -tmpf_15 * win_bt[6];
      out[7] = -tmpf_16 * win_bt[7];
      out[8] = -tmpf_17 * win_bt[8];
      out[9] = tmpf_17 * win_bt[9];
      out[10] = tmpf_16 * win_bt[10];
      out[11] = tmpf_15 * win_bt[11];
      out[12] = tmpf_14 * win_bt[12];
      out[13] = tmpf_13 * win_bt[13];
      out[14] = tmpf_12 * win_bt[14];
      out[15] = tmpf_11 * win_bt[15];
      out[16] = tmpf_10 * win_bt[16];
      out[17] = tmpf_9 * win_bt[17];
      out[18] = tmpf_8 * win_bt[18];
      out[19] = tmpf_7 * win_bt[19];
      out[20] = tmpf_6 * win_bt[20];
      out[21] = tmpf_5 * win_bt[21];
      out[22] = tmpf_4 * win_bt[22];
      out[23] = tmpf_3 * win_bt[23];
      out[24] = tmpf_2 * win_bt[24];
      out[25] = tmpf_1 * win_bt[25];
      out[26] = tmpf_0 * win_bt[26];
      out[27] = tmpf_0 * win_bt[27];
      out[28] = tmpf_1 * win_bt[28];
      out[29] = tmpf_2 * win_bt[29];
      out[30] = tmpf_3 * win_bt[30];
      out[31] = tmpf_4 * win_bt[31];
      out[32] = tmpf_5 * win_bt[32];
      out[33] = tmpf_6 * win_bt[33];
      out[34] = tmpf_7 * win_bt[34];
      out[35] = tmpf_8 * win_bt[35];
    }
  }


    /**
     *  Reads the side info from the stream, assuming the entire. frame has been
     *  read already. Mono : 136 bits (= 17 bytes) Stereo : 256 bits (= 32
     *  bytes)
     *
     *@return    Description of the Returned Value
     */
    private final boolean get_side_info() {
        int ch;
        int gr;
        if (header.version() == Header.MPEG1) {
            si.main_data_begin = stream.readbits(9);
            if (channels == 1) {
                si.private_bits = stream.readbits(5);
            } else {
                si.private_bits = stream.readbits(3);
            }

            for (ch = 0; ch < channels; ch++) {
                LayerIIIDecoder.Channel t = si.ch[ch];
                t.scfsi[0] = stream.readbits(1);
                t.scfsi[1] = stream.readbits(1);
                t.scfsi[2] = stream.readbits(1);
                t.scfsi[3] = stream.readbits(1);
            }

            for (gr = 0; gr < 2; gr++) {
                for (ch = 0; ch < channels; ch++) {
                    LayerIIIDecoder.GRInfo s = si.ch[ch].gr[gr];
                    s.part2_3_length = stream.readbits(12);
                    s.big_values = stream.readbits(9);
                    s.global_gain = stream.readbits(8);
                    s.scalefac_compress = stream.readbits(4);
                    s.window_switching_flag = stream.readbits(1);
                    if ((s.window_switching_flag) != 0) {
                        s.block_type = stream.readbits(2);
                        s.mixed_block_flag = stream.readbits(1);
                        s.table_select[0] = stream.readbits(5);
                        s.table_select[1] = stream.readbits(5);
                        s.subblock_gain[0] = stream.readbits(3);
                        s.subblock_gain[1] = stream.readbits(3);
                        s.subblock_gain[2] = stream.readbits(3);
                        // Set region_count parameters since they are implicit in this case.
                        if (s.block_type == 0) {
                            //	 Side info bad: block_type == 0 in split block
                            return false;
                        } else if (s.block_type == 2 && s.mixed_block_flag == 0) {
                            s.region0_count = 8;
                        } else {
                            s.region0_count = 7;
                        }
                        s.region1_count = 20 - s.region0_count;
                    } else {
                        s.table_select[0] = stream.readbits(5);
                        s.table_select[1] = stream.readbits(5);
                        s.table_select[2] = stream.readbits(5);
                        s.region0_count = stream.readbits(4);
                        s.region1_count = stream.readbits(3);
                        s.block_type = 0;
                    }
                    s.preflag = stream.readbits(1);
                    s.scalefac_scale = stream.readbits(1);
                    s.count1table_select = stream.readbits(1);
                }
            }
        } else {
            //unused currently
            // MPEG-2 LSF
            si.main_data_begin = stream.readbits(8);
            if (channels == 1) {
                si.private_bits = stream.readbits(1);
            } else {
                si.private_bits = stream.readbits(2);
            }
            for (ch = 0; ch < channels; ch++) {
                LayerIIIDecoder.GRInfo s = si.ch[ch].gr[0];
                s.part2_3_length = stream.readbits(12);
                s.big_values = stream.readbits(9);
                s.global_gain = stream.readbits(8);
                s.scalefac_compress = stream.readbits(9);
                s.window_switching_flag = stream.readbits(1);
                if ((s.window_switching_flag) != 0) {
                    s.block_type = stream.readbits(2);
                    s.mixed_block_flag = stream.readbits(1);
                    s.table_select[0] = stream.readbits(5);
                    s.table_select[1] = stream.readbits(5);
                    s.subblock_gain[0] = stream.readbits(3);
                    s.subblock_gain[1] = stream.readbits(3);
                    s.subblock_gain[2] = stream.readbits(3);
                    // Set region_count parameters since they are implicit in this case.
                    if (s.block_type == 0) {
                        // Side info bad: block_type == 0 in split block
                        return false;
                    } else if (s.block_type == 2 && s.mixed_block_flag == 0) {
                        s.region0_count = 8;
                    } else {
                        s.region0_count = 7;
                        s.region1_count = 20 - s.region0_count;
                    }
                } else {
                    s.table_select[0] = stream.readbits(5);
                    s.table_select[1] = stream.readbits(5);
                    s.table_select[2] = stream.readbits(5);
                    s.region0_count = stream.readbits(4);
                    s.region1_count = stream.readbits(3);
                    s.block_type = 0;
					s.mixed_block_flag = 0;
                }
                s.scalefac_scale = stream.readbits(1);
                s.count1table_select = stream.readbits(1);
            }
        }

        return true;
    }

	private static final byte stab[][][] = {
	 { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,
	   { 7, 7, 7,0 } , { 6, 6, 6,3 } , {  8, 8,5,0} } ,
	 { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,
	   {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,
	 { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,
	   { 6,15,12,0 } , { 6,12, 9,6 } , {  6,18,9,0} } }; 

	private static int n_slen2[] = new int[512]; /* MPEG 2.0 slen for 'normal' mode */
	private static int i_slen2[] = new int[256]; /* MPEG 2.0 slen for intensity stereo */
	
	static {
		int i,j,k,l;
		for(i=0;i<5;i++) {
		  for(j=0;j<6;j++) {
			for(k=0;k<6;k++) {
			  int n = k + j * 6 + i * 36;
			  i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
			}
		  }
		}
		for(i=0;i<4;i++) {
		  for(j=0;j<4;j++) {
			for(k=0;k<4;k++) {
			  int n = k + j * 4 + i * 16;
			  i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
			}
		  }
		}
		for(i=0;i<4;i++) {
		  for(j=0;j<3;j++) {
			int n = j + i * 3;
			i_slen2[n+244] = i|(j<<3) | (5<<12);
			n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
		  }
		}

		for(i=0;i<5;i++) {
		  for(j=0;j<5;j++) {
			for(k=0;k<4;k++) {
			  for(l=0;l<4;l++) {
				int n = l + k * 4 + j * 16 + i * 80;
				n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
			  }
			}
		  }
		}
		for(i=0;i<5;i++) {
		  for(j=0;j<5;j++) {
			for(k=0;k<4;k++) {
			  int n = k + j * 4 + i * 20;
			  n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
			}
		  }
		}
	}

	private final void get_scale_factors_2(final int ch, final int gr)
	{
	  byte[] pnt;
	  int i,j, k;
	  int slen;   
	  int n = 0;
	  int numbits = 0;
	  int l[] = null;
	  int s[][] = null;
	  int scf = 0;
	  boolean i_stereo = ((header.mode() == Header.JOINT_STEREO) && ((header.mode_extension() & 0x1) != 0));	  
	  GRInfo gr_info = (si.ch[ch].gr[gr]);
	  
	  if(ch == 0){
		l = scalefac0L;
		s = scalefac0S;
	  }
	  else{
		l = scalefac1L;
		s = scalefac1S;
	  }

	  if((ch > 0) && i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */
		slen = i_slen2[gr_info.scalefac_compress >> 1];
	  else
		slen = n_slen2[gr_info.scalefac_compress];
		
	  gr_info.preflag = (slen >> 15) & 0x1;

	  n = 0;  
	  if( gr_info.block_type == 2 ) {
		n++;
		if ((gr_info.mixed_block_flag) != 0) {
			// TODO add mixed mode support
			System.out.println("mixed mode is unsupported!");
			n++;
		}

		pnt = stab[n][(slen>>12) & 0x7];

		for(i = 0; i < 4; i++) {
		  int num = slen & 0x7;
		  slen >>= 3;
		  if(num != 0) {
			for(j = 0; j < pnt[i]; j+=3) {
				for(k = 0; k < 3; k++) {
					s[k][scf] = br.hgetbits(num);
				}
				scf++;
			}
			numbits += pnt[i] * num;
		  }
		  else {
			for(j = 0; j < pnt[i]; j+=3) {
				for(k = 0; k < 3; k++) {
				  s[k][scf] = 0;
				}
				scf++;
		  	}
		  }
		} 
  
		n = (n << 1) + 1;
		for(i = 0; i < n; i+=3) {
			for(k = 0; k < 3; k++) {
				s[k][scf] = 0;
			}
			scf++;
		}
	  } else {
		pnt = stab[n][(slen>>12) & 0x7];

		for(i = 0; i < 4; i++) {
		  int num = slen & 0x7;
		  slen >>= 3;
		  if(num != 0) {
			for(j = 0; j < pnt[i]; j++) {
			  l[scf++] = br.hgetbits(num);
			}
			numbits += pnt[i] * num;
		  }
		  else {
			for(j = 0; j < pnt[i]; j++)
			  l[scf++] = 0;
		  }
		} 
  
		n = (n << 1) + 1;
		for(i = 0; i < n; i++) {
		  l[scf++] = 0;
		}
	  }
	}

    private final void get_scale_factors_1(final int ch, final int gr) {
        GRInfo gr_info = (si.ch[ch].gr[gr]);
        int scale_comp = gr_info.scalefac_compress;
        int length0 = slen0[scale_comp];
        int length1 = slen1[scale_comp];
        int l[] = null;
        int s[][] = null;
        if(ch==0){
          l = scalefac0L;
          s = scalefac0S;
        }
        else{
          l = scalefac1L;
          s = scalefac1S;
        }
        if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
           if ((gr_info.mixed_block_flag) != 0) {
              // MIXED
                for (int sfb = 0; sfb < 8; sfb++) {
                    l[sfb] = br.hgetbits(slen0[gr_info.scalefac_compress]);
                }
                for (int sfb = 3; sfb < 6; sfb++) {
                    for (int window = 0; window < 3; window++) {
                      s[window][sfb] = br.hgetbits(slen0[gr_info.scalefac_compress]);
                    }
                }
                for (int sfb = 6; sfb < 12; sfb++) {
                    for (int window = 0; window < 3; window++) {
                      s[window][sfb] = br.hgetbits(slen1[gr_info.scalefac_compress]);
                    }
                }
                for (int sfb = 12, window = 0; window < 3; window++) {
                    s[window][sfb] = 0;
                }
            }
            else {
                // SHORT
                s[0][0] = br.hgetbits(length0);
                s[1][0] = br.hgetbits(length0);
                s[2][0] = br.hgetbits(length0);
                s[0][1] = br.hgetbits(length0);
                s[1][1] = br.hgetbits(length0);
                s[2][1] = br.hgetbits(length0);
                s[0][2] = br.hgetbits(length0);
                s[1][2] = br.hgetbits(length0);
                s[2][2] = br.hgetbits(length0);
                s[0][3] = br.hgetbits(length0);
                s[1][3] = br.hgetbits(length0);
                s[2][3] = br.hgetbits(length0);
                s[0][4] = br.hgetbits(length0);
                s[1][4] = br.hgetbits(length0);
                s[2][4] = br.hgetbits(length0);
                s[0][5] = br.hgetbits(length0);
                s[1][5] = br.hgetbits(length0);
                s[2][5] = br.hgetbits(length0);
                s[0][6] = br.hgetbits(length1);
                s[1][6] = br.hgetbits(length1);
                s[2][6] = br.hgetbits(length1);
                s[0][7] = br.hgetbits(length1);
                s[1][7] = br.hgetbits(length1);
                s[2][7] = br.hgetbits(length1);
                s[0][8] = br.hgetbits(length1);
                s[1][8] = br.hgetbits(length1);
                s[2][8] = br.hgetbits(length1);
                s[0][9] = br.hgetbits(length1);
                s[1][9] = br.hgetbits(length1);
                s[2][9] = br.hgetbits(length1);
                s[0][10] = br.hgetbits(length1);
                s[1][10] = br.hgetbits(length1);
                s[2][10] = br.hgetbits(length1);
                s[0][11] = br.hgetbits(length1);
                s[1][11] = br.hgetbits(length1);
                s[2][11] = br.hgetbits(length1);
                s[0][12] = s[1][12] = s[2][12] = 0;
            }
            // SHORT
        } else {
            // LONG types 0,1,3
            int si_t[] = si.ch[ch].scfsi;
            if (gr == 0) {
                l[0] = br.hgetbits(length0);
                l[1] = br.hgetbits(length0);
                l[2] = br.hgetbits(length0);
                l[3] = br.hgetbits(length0);
                l[4] = br.hgetbits(length0);
                l[5] = br.hgetbits(length0);
                l[6] = br.hgetbits(length0);
                l[7] = br.hgetbits(length0);
                l[8] = br.hgetbits(length0);
                l[9] = br.hgetbits(length0);
                l[10] = br.hgetbits(length0);
                l[11] = br.hgetbits(length1);
                l[12] = br.hgetbits(length1);
                l[13] = br.hgetbits(length1);
                l[14] = br.hgetbits(length1);
                l[15] = br.hgetbits(length1);
                l[16] = br.hgetbits(length1);
                l[17] = br.hgetbits(length1);
                l[18] = br.hgetbits(length1);
                l[19] = br.hgetbits(length1);
                l[20] = br.hgetbits(length1);
            }
            else{
              if (si_t[0] == 0) {
                l[0] = br.hgetbits(length0);
                l[1] = br.hgetbits(length0);
                l[2] = br.hgetbits(length0);
                l[3] = br.hgetbits(length0);
                l[4] = br.hgetbits(length0);
                l[5] = br.hgetbits(length0);
              }
              if (si_t[1] == 0) {
                l[6] = br.hgetbits(length0);
                l[7] = br.hgetbits(length0);
                l[8] = br.hgetbits(length0);
                l[9] = br.hgetbits(length0);
                l[10] = br.hgetbits(length0);
              }
              if (si_t[2] == 0) {
                l[11] = br.hgetbits(length1);
                l[12] = br.hgetbits(length1);
                l[13] = br.hgetbits(length1);
                l[14] = br.hgetbits(length1);
                l[15] = br.hgetbits(length1);
              }
              if (si_t[3] == 0) {
                l[16] = br.hgetbits(length1);
                l[17] = br.hgetbits(length1);
                l[18] = br.hgetbits(length1);
                l[19] = br.hgetbits(length1);
                l[20] = br.hgetbits(length1);
              }
            }
            l[21] = l[22] = 0;
        }
    }


    private final void huffman_decode(final int ch, final int gr) {
        //huff.x = huff.y = huff.v = huff.w= 0;
        GRInfo s = si.ch[ch].gr[gr];
        int part2_3_end = part2_start + s.part2_3_length;
        int num_bits=0;
        int region1Start=0;
        int region2Start=0;
        int index;
        int buf;
        int buf1;

        // Find region boundary for short block case
        if (((s.window_switching_flag) != 0) && (s.block_type == 2)) {
            // Region2.
            region1Start = 36;
            // sfb[9/3]*3=36
            region2Start = 576;
            // No Region2 for short block case
        } else {
            // Find region boundary for long block case
            buf = s.region0_count + 1;
            buf1 = buf + s.region1_count + 1;
            if (buf1 > sfBandIndexL.length - 1) {
                buf1 = sfBandIndexL.length - 1;
            }
            region1Start = sfBandIndexL[buf];
            region2Start = sfBandIndexL[buf1];
        }
        index = 0;
        // Read bigvalues area
        int big_val_max, is_1d_max;

        big_val_max = s.big_values << 1;
        is_1d_max = is_1d.length;
       // for (int i = 0; (i < (s.big_values << 1)) && (i<is_1d.length); i += 2) {
        for (int i = 0; (i<big_val_max) && (i<is_1d_max); i += 2) {
            if (i < region1Start) {
                h = HuffmanTables.ht[s.table_select[0]];
            }
            else if (i < region2Start) {
                h = HuffmanTables.ht[s.table_select[1]];
            }
            else {
                h = HuffmanTables.ht[s.table_select[2]];
            }
            hDecoder.decode(h, huff, br);
            is_1d[index++] = huff.x;
            is_1d[index++] = huff.y;
        }

        h = HuffmanTables.ht[s.count1table_select + 32];
        num_bits = br.totbit;
        while ((num_bits < part2_3_end) && (index < 576)) {
            hDecoder.decode(h, huff, br);
            is_1d[index++] = huff.v;
            is_1d[index++] = huff.w;
            is_1d[index++] = huff.x;
            is_1d[index++] = huff.y;
            num_bits = br.totbit;
        }

        if (num_bits > part2_3_end) {
            br.rewindNbits(num_bits - part2_3_end);
            index -= 4;
        }

        num_bits = br.totbit;
        // Dismiss stuffing bits
        if (num_bits < part2_3_end) {
            br.hgetbits(part2_3_end - num_bits);
        }

        // Zero out rest
        if (index < 576) {
            if(ch==0)
              nonzero0 = index;
            else
              nonzero1 = index;
        } else {
            if(ch==0)
              nonzero0 = 576;
            else
              nonzero1 = 576;
        }
        if (index < 0) {
            index = 0;
        }
    }

    private final void dequantize_sample(final float xr[][], final int ch, final int gr) {
        GRInfo gr_info = (si.ch[ch].gr[gr]);
        int cb = 0;
        int next_cb_boundary =0;
        int cb_begin = 0;
        int cb_width = 0;
        float g_gain = 0.0f;
        // choose correct scalefactor band per block type, initalize boundary
        if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
            if (gr_info.mixed_block_flag != 0) {
                next_cb_boundary = sfBandIndexL[1];
            }
            // LONG blocks: 0,1,3
            else {
                cb_width = sfBandIndexS[1];
                next_cb_boundary = (cb_width << 2) - cb_width;
                cb_begin = 0;
            }
        } else {
            next_cb_boundary = sfBandIndexL[1];
            // LONG blocks: 0,1,3
        }
        // Compute overall (global) scaling.
        g_gain = (float) Math.pow(2.0, (0.25 * (gr_info.global_gain - 210.0)));
        int maxNonZero = (ch == 0) ? nonzero0 : nonzero1;
        for (int j = 0; j < maxNonZero; j++) {
            reste = j % SSLIMIT;
            quotien = (int) ((j - reste) / SSLIMIT);
            if (is_1d[j] == 0) {
                xr[quotien][reste] = 0.0f;
            }
            else {
              int abv = is_1d[j];
              if (is_1d[j] > 0) {
                xr[quotien][reste] = g_gain * t_43[abv];
              }
              else {
                xr[quotien][reste] = -g_gain * t_43[-abv];
              }
            }
        }
        // apply formula per block type
        for (int i=0, j = 0; j < maxNonZero; j++,i++) {
            reste = j % SSLIMIT;
            quotien = (int) ((j - reste) / SSLIMIT);
            if (i == next_cb_boundary) {
                /*
                 *  Adjust critical band boundary
                 */
                if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
                    if (gr_info.mixed_block_flag != 0) {
                        if (i == sfBandIndexL[8]) {
                            next_cb_boundary = sfBandIndexS[4];
                            next_cb_boundary = (next_cb_boundary << 2) - next_cb_boundary;
                            cb = 3;
                            cb_width = sfBandIndexS[4] - sfBandIndexS[3];
                            cb_begin = sfBandIndexS[3];
                            cb_begin = (cb_begin << 2) - cb_begin;
                        } else if (i < sfBandIndexL[8]) {
                            next_cb_boundary = sfBandIndexL[(++cb) + 1];
                        } else {
                            next_cb_boundary = sfBandIndexS[(++cb) + 1];
                            next_cb_boundary = (next_cb_boundary << 2) - next_cb_boundary;
                            cb_begin = sfBandIndexS[cb];
                            cb_width = sfBandIndexS[cb + 1] - cb_begin;
                            cb_begin = (cb_begin << 2) - cb_begin;
                        }
                    } else {
                        next_cb_boundary = sfBandIndexS[(++cb) + 1];
                        next_cb_boundary = (next_cb_boundary << 2) - next_cb_boundary;
                        cb_begin = sfBandIndexS[cb];
                        cb_width = sfBandIndexS[cb + 1] - cb_begin;
                        cb_begin = (cb_begin << 2) - cb_begin;
                    }
                } else {
                    // long blocks
                    next_cb_boundary = sfBandIndexL[(++cb) + 1];
                }
            }
            int s[][] = (ch==0)?scalefac0S:scalefac1S;
            int l[] = (ch==0)?scalefac0L:scalefac1L;
            // Do long/short dependent scaling operations
            if ((gr_info.window_switching_flag != 0) && (((gr_info.block_type == 2) && (gr_info.mixed_block_flag == 0)) || ((gr_info.block_type == 2) && (gr_info.mixed_block_flag != 0) && (j >= 36)))) {
                int t_index = (i - cb_begin) / cb_width;
                int idx = s[t_index][cb] << gr_info.scalefac_scale;
                idx += (gr_info.subblock_gain[t_index] << 2);
                xr[quotien][reste] *= two_to_negative_half_pow[idx];
            } else {
                // LONG block types 0,1,3 & 1st 2 subbands of switched blocks
                int idx = l[cb];
                if (gr_info.preflag != 0) {
                    idx += pretab[cb];
                }
                idx = idx << gr_info.scalefac_scale;
                xr[quotien][reste] *= two_to_negative_half_pow[idx];
            }
        }

        int reste;
        int quotien;
        for(int j = maxNonZero; j < 576; j++) {
            reste = j % SSLIMIT;
            quotien = (int) ((j - reste) / SSLIMIT);
            xr[quotien][reste] = 0.0f;
        }
    }


    int freq, freq3, src_line, des_line, sfb_start, sfb_start3, sfb_lines, reste, quotien;

    private final void reorder(final float xr[][], final int ch, final int gr) {
        GRInfo gr_info = (si.ch[ch].gr[gr]);

        if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
          if (gr_info.mixed_block_flag != 0) {
                // NO REORDER FOR LOW 2 SUBBANDS
                for(int i = 36; --i >= 0;){//i = 0; i < 36; i++) {
                    reste = i % SSLIMIT;
                    quotien = (int) ((i - reste) / SSLIMIT);
                    out_1d[i] = xr[quotien][reste];
                }
                // REORDERING FOR REST SWITCHED SHORT
                for (int sfb = 3, sfb_start = sfBandIndexS[3], sfb_lines = sfBandIndexS[4] - sfb_start; sfb < 13;
                        sfb++, sfb_start = sfBandIndexS[sfb], sfb_lines = sfBandIndexS[sfb + 1] - sfb_start) {
                    sfb_start3 = (sfb_start << 2) - sfb_start;
                    for (freq = 0, freq3 = 0; freq < sfb_lines; freq++, freq3 += 3) {
                        src_line = sfb_start3 + freq;
                        des_line = sfb_start3 + freq3;
                        reste = src_line % SSLIMIT;
                        quotien = (int) ((src_line - reste) / SSLIMIT);
                        out_1d[des_line] = xr[quotien][reste];
                        src_line += sfb_lines;
                        des_line++;
                        reste = src_line % SSLIMIT;
                        quotien = (int) ((src_line - reste) / SSLIMIT);
                        out_1d[des_line] = xr[quotien][reste];
                        src_line += sfb_lines;
                        des_line++;
                        reste = src_line % SSLIMIT;
                        quotien = (int) ((src_line - reste) / SSLIMIT);
                        out_1d[des_line] = xr[quotien][reste];
                    }
                }
            } else {
                // pure short
              int reorder[] = reorder_table[sfreq];
              for(int i = 576; --i >= 0;){//while(i < 576){
                  int j = reorder[i];
                  reste = j % SSLIMIT;
                  quotien = (int) ((j - reste) / SSLIMIT);
                  out_1d[i] = xr[quotien][reste];
                }
            }
        }
        else {
            // long blocks
            for(int i = 576; --i >= 0;){
              reste = i % SSLIMIT;
              quotien = (int) ((i - reste) / SSLIMIT);
              out_1d[i] = xr[quotien][reste];
            }
        }
    }

    private final void stereo(final int gr) {
        if (channels == 1) {
            for(int sb = SBLIMIT; --sb >= 0;) {
                float l[] = lr[0][sb];
                float r[] = ro[0][sb];
                for (int ss = 0; ss < SSLIMIT; ss+=3) {
                    l[ss] = r[ss];
                    l[ss + 1] = r[ss + 1];
                    l[ss + 2] = r[ss + 2];
                }
            }
        }
        else {
            GRInfo gr_info = (si.ch[0].gr[gr]);
            int mode_ext = header.mode_extension();
           // boolean ms_stereo = ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x2) != 0));
            boolean i_stereo = ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x1) != 0));
            //boolean lsf = ((header.version() == Header.MPEG2_LSF));
            int io_type = (gr_info.scalefac_compress & 1);
            // initialization
            /*
            for (i = 0; i < 576;) {
                is_pos[i] = 7;
                is_ratio[i++] = 0.0f;
                is_pos[i] = 7;
                is_ratio[i++] = 0.0f;
                is_pos[i] = 7;
                is_ratio[i++] = 0.0f;
                is_pos[i] = 7;
                is_ratio[i++] = 0.0f;
            }
            */
            for(int i = 0; i < is_pos.length; i++){
            	is_pos[i] = 7;
            }
            // Arrays.fill(is_pos, 7);
            //Arrays.fill(is_ratio, 0);

            if (i_stereo) {
                if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
                    if (gr_info.mixed_block_flag != 0) {
                        int max_sfb = 0;
                        for (int j = 0; j < 3; j++) {
                            int sfbcnt;
                            sfbcnt = 2;
                            for (int sfb = 12; sfb >= 3; sfb--) {
                                int i = sfBandIndexS[sfb];
                                int lines = sfBandIndexS[sfb + 1] - i;
                                i = (i << 2) - i + (j + 1) * lines - 1;
                                while (lines > 0) {
                                    if (ro[1][i / 18][i % 18] != 0.0f) {
                                        sfbcnt = sfb;
                                        sfb = -10;
                                        lines = -10;
                                    }
                                    lines--;
                                    i--;
                                }
                            }
                            int sfb = sfbcnt + 1;
                            if (sfb > max_sfb) {
                                max_sfb = sfb;
                            }
                            int stemp[][] =  scalefac1S;
                            while (sfb < 12) {
                                int temp = sfBandIndexS[sfb];
                                int sb = sfBandIndexS[sfb + 1] - temp;
                                int i = (temp << 2) - temp + j * sb;
                                for (; sb > 0; sb--) {
                                    is_pos[i] = stemp[j][sfb];
                                    if (is_pos[i] != 7) {
                                        //if (lsf) {
                                        //    i_stereo_k_values(is_pos[i], io_type, i);
                                        //}
                                        //else {
                                            is_ratio[i] = TAN12[is_pos[i]];
                                        //}
                                    }
                                    i++;
                                }
                                sfb++;
                            }
                            sfb = sfBandIndexS[10];
                            int sb = sfBandIndexS[11] - sfb;
                            sfb = (sfb << 2) - sfb + j * sb;
                            int temp = sfBandIndexS[11];
                            sb = sfBandIndexS[12] - temp;
                            int i = (temp << 2) - temp + j * sb;
                            for (; sb > 0; sb--) {
                                is_pos[i] = is_pos[sfb];
                                //if (lsf) {
                                //    k[0][i] = k[0][sfb];
                                //    k[1][i] = k[1][sfb];
                                //} else {
                                    is_ratio[i] = is_ratio[sfb];
                                //}
                                i++;
                            }
                        }
                        if (max_sfb <= 3) {
                            int i = 2;
                            int ss = 17;
                            int sb = -1;
                            while (i >= 0) {
                                if (ro[1][i][ss] != 0.0f) {
                                    sb = (i << 4) + (i << 1) + ss;
                                    i = -1;
                                } else {
                                    ss--;
                                    if (ss < 0) {
                                        i--;
                                        ss = 17;
                                    }
                                }
                            }
                            i = 0;
                            while (sfBandIndexL[i] <= sb) {
                                i++;
                            }
                            int sfb = i;
                            i = sfBandIndexL[i];
                            int[] l = scalefac1L;
                            for (; sfb < 8; sfb++) {
                                sb = sfBandIndexL[sfb + 1] - sfBandIndexL[sfb];
                                for (; sb > 0; sb--) {
                                    is_pos[i] = l[sfb];
                                    if (is_pos[i] != 7) {
                                        //if (lsf) {
                                        //    i_stereo_k_values(is_pos[i], io_type, i);
                                       // } else {
                                            is_ratio[i] = TAN12[is_pos[i]];
                                       // }
                                    }
                                    i++;
                                }

                            }

                        }

                    } else {

                        for (int j = 0; j < 3; j++) {
                            int sfbcnt;
                            sfbcnt = -1;
                            for (int sfb = 12; sfb >= 0; sfb--) {
                                int temp = sfBandIndexS[sfb];
                                int lines = sfBandIndexS[sfb + 1] - temp;
                                int i = (temp << 2) - temp + (j + 1) * lines - 1;
                                while (lines > 0) {
                                    if (ro[1][i / 18][i % 18] != 0.0f) {
                                        sfbcnt = sfb;
                                        sfb = -10;
                                        lines = -10;
                                    }
                                    lines--;
                                    i--;
                                }
                            }
                            int sfb = sfbcnt + 1;
                            while (sfb < 12) {
                                int temp = sfBandIndexS[sfb];
                                int sb = sfBandIndexS[sfb + 1] - temp;
                                int i = (temp << 2) - temp + j * sb;
                                for (; sb > 0; sb--) {
                                    is_pos[i] = scalefac1S[j][sfb];
                                    if (is_pos[i] != 7) {
                                        //if (lsf) {
                                        //    i_stereo_k_values(is_pos[i], io_type, i);
                                        //} else {
                                            is_ratio[i] = TAN12[is_pos[i]];
                                        //}
                                    }
                                    i++;
                                }
                                sfb++;
                            }

                            int temp = sfBandIndexS[10];
                            int temp2 = sfBandIndexS[11];
                            int sb = temp2 - temp;
                            sfb = (temp << 2) - temp + j * sb;
                            sb = sfBandIndexS[12] - temp2;
                            int i = (temp2 << 2) - temp2 + j * sb;
                            float k0 = k[0][sfb];
                            float k1 = k[1][sfb];
                            for (; sb > 0; sb--) {
                                is_pos[i] = is_pos[sfb];
                                //if (lsf) {
                                //    k[0][i] = k0;
                                //   k[1][i] = k1;
                                //} else {
                                    is_ratio[i] = is_ratio[sfb];
                                //}
                                i++;
                            }

                        }

                    }

                } else {

                    int i = 31;
                    int ss = 17;
                    int sb = 0;
                    while (i >= 0) {
                        if (ro[1][i][ss] != 0.0f) {
                            sb = (i << 4) + (i << 1) + ss;
                            i = -1;
                        } else {
                            ss--;
                            if (ss < 0) {
                                i--;
                                ss = 17;
                            }
                        }
                    }
                    i = 0;
                    while (sfBandIndexL[i] <= sb) {
                        i++;
                    }
                    int sfb = i;
                    i = sfBandIndexL[i];
                    for (; sfb < 21; sfb++) {
                        sb = sfBandIndexL[sfb + 1] - sfBandIndexL[sfb];
                        for (; sb > 0; sb--) {
                            int is_pos_t = scalefac1L[sfb];
                            is_pos[i] = is_pos_t;
                            if (is_pos_t != 7) {
                                //if (lsf) {
                                //    i_stereo_k_values(is_pos_t, io_type, i);
                                //} else {
                                    is_ratio[i] = TAN12[is_pos_t];
                                //}
                            }
                            i++;
                        }
                    }
                    sfb = sfBandIndexL[20];
                    for (sb = 576 - sfBandIndexL[21]; (sb > 0) && (i < 576); sb--, i++) {
                        is_pos[i] = is_pos[sfb];
                        // error here : i >=576
                        //if (lsf) {
                        //    k[0][i] = k[0][sfb];
                        //    k[1][i] = k[1][sfb];
                        //}/ else {
                            is_ratio[i] = is_ratio[sfb];
                        //}

                    }
                }
            }
            int i = 0;
            for (int sb = 0; sb < SBLIMIT; sb++) {
                float []lr0 = lr[0][sb];
                float []lr1 = lr[1][sb];
                float []ro0 = ro[0][sb];
                float []ro1 = ro[1][sb];
                for (int ss = 0; ss < SSLIMIT; ss++, i++) {
                    if (is_pos[i] == 7) {
                        if ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x2) != 0)){//(ms_stereo) {
                            lr0[ss] = (ro0[ss] + ro1[ss]) * 0.707106781f;
                            lr1[ss] = (ro0[ss] - ro1[ss]) * 0.707106781f;
                        } else {
                            lr0[ss] = ro0[ss];
                            lr1[ss] = ro1[ss];
                        }
                    }
                    else if (i_stereo) {
                        //if (lsf) {
                        //    lr0[ss] = ro0[ss] * k[0][i];
                        //    lr1[ss] = ro0[ss] * k[1][i];
                        //} else {
                            lr1[ss] = ro0[ss] / (float) (1 + is_ratio[i]);
                            lr0[ss] = lr1[ss] * is_ratio[i];
                        //}
                    }

                }
            }
        }
    }




    private final static float cs[] =
            {
            0.857492925712f, 0.881741997318f, 0.949628649103f, 0.983314592492f,
            0.995517816065f, 0.999160558175f, 0.999899195243f, 0.999993155067f
            };

    private final static float ca[] =
            {
            -0.5144957554270f, -0.4717319685650f, -0.3133774542040f, -0.1819131996110f,
            -0.0945741925262f, -0.0409655828852f, -0.0141985685725f, -0.00369997467375f
            };

    private final void antialias(final int ch, final int gr) {
        GRInfo gr_info = (si.ch[ch].gr[gr]);

        int sb18lim = 0;

        if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2) && (gr_info.mixed_block_flag == 0)) {
           return;
        }
        if ((gr_info.window_switching_flag != 0) && (gr_info.mixed_block_flag != 0) && (gr_info.block_type == 2)) {
            sb18lim = 18;
        }
        else {
            sb18lim = 558;
        }

        for (int sb18 = 0; sb18 < sb18lim; sb18 += 18) {
             int src_idx1 = sb18 + 17;
             int src_idx2 = sb18 + 18;
             float bu = out_1d[src_idx1];
             float bd = out_1d[src_idx2];
             float cst = cs[0];
             float cat = ca[0];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[1];
             cat = ca[1];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[2];
             cat = ca[2];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[3];
             cat = ca[3];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[4];
             cat = ca[4];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[5];
             cat = ca[5];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[6];
             cat = ca[6];
             out_1d[src_idx1--] = (bu * cst) - (bd * cat);
             out_1d[src_idx2++] = (bd * cst) + (bu * cat);
             bu = out_1d[src_idx1];
             bd = out_1d[src_idx2];
             cst = cs[7];
             cat = ca[7];
             out_1d[src_idx1] = (bu * cst) - (bd * cat);
             out_1d[src_idx2] = (bd * cst) + (bu * cat);
        }
    }

    private final void hybrid(final int ch, final int gr) {
        GRInfo gr_info = (si.ch[ch].gr[gr]);
        for (int sb18 = 0; sb18 < 576; sb18 += 18) {
            int bt = ((gr_info.window_switching_flag != 0) && (gr_info.mixed_block_flag != 0) && (sb18 < 36)) ? 0 : gr_info.block_type;

            for (int cc = 0; cc < 18; cc++) {
                tsOutCopy[cc] = out_1d[cc + sb18];
            }

            invMDCT(tsOutCopy, rawout, bt);

            for (int cc = 0; cc < 18; cc++) {
                out_1d[cc + sb18] = tsOutCopy[cc];
            }

            int sbt = sb18;
            out_1d[sbt] = rawout[0] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[18];
            out_1d[sbt] = rawout[1] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[19];
            out_1d[sbt] = rawout[2] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[20];
            out_1d[sbt] = rawout[3] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[21];
            out_1d[sbt] = rawout[4] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[22];
            out_1d[sbt] = rawout[5] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[23];
            out_1d[sbt] = rawout[6] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[24];
            out_1d[sbt] = rawout[7] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[25];
            out_1d[sbt] = rawout[8] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[26];
            out_1d[sbt] = rawout[9] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[27];
            out_1d[sbt] = rawout[10] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[28];
            out_1d[sbt] = rawout[11] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[29];
            out_1d[sbt] = rawout[12] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[30];
            out_1d[sbt] = rawout[13] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[31];
            out_1d[sbt] = rawout[14] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[32];
            out_1d[sbt] = rawout[15] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[33];
            out_1d[sbt] = rawout[16] + prevblck[ch][sbt];
            prevblck[ch][sbt++] = rawout[34];
            out_1d[sbt] = rawout[17] + prevblck[ch][sbt];
            prevblck[ch][sbt] = rawout[35];
        }
    }

    private static final class GRInfo {
      private int part2_3_length;
      private int big_values;
      private int global_gain;
      private int scalefac_compress;
      private int window_switching_flag;
      private int block_type;
      private int mixed_block_flag;
      private final int[] table_select = new int[3];
      private final int[] subblock_gain = new int[3];
      private int region0_count;
      private int region1_count;
      private int preflag;
      private int scalefac_scale;
      private int count1table_select;
    }

    private static final class SideInfo {
      private int main_data_begin;
      private int private_bits;
      private final Channel[] ch= new Channel[2];

      public SideInfo() {
        ch[0] = new Channel();
        ch[1] = new Channel();
      }
    }

    private static final class Channel {
      private final int[] scfsi = new int[4];
      private final GRInfo[] gr= new GRInfo[2];

      public Channel() {
        gr[0] = new GRInfo();
        gr[1] = new GRInfo();
      }
    }

}